home *** CD-ROM | disk | FTP | other *** search
/ Power Programmierung / Power-Programmierung (Tewi)(1994).iso / magazine / progjour / 1988 / 02 / ongraf62.l1 next >
Text File  |  1988-02-18  |  6KB  |  218 lines

  1. Code from "Yet Another VGA Write Mode" by Michael Abrash, PJ,
  2. Volume 6.2. Copyright 1987 Michael Abrash
  3. ;
  4. ; *** Listing 1 ***
  5. ;
  6. ; Program to illustrate one use of write mode 2 of the VGA and EGA by
  7. ; animating the image of an "A" drawn by copying it from a chunky
  8. ; bit-map in system memory to a planar bit-map in VGA or EGA memory.
  9. ;
  10. ; Assembled with MASM 5.0, linked with MS-LINK 3.60.
  11. ;
  12. ; By Michael Abrash 11/8/87
  13. ;
  14. Stack    segment    para stack 'STACK'
  15.     db    512 dup(0)
  16. Stack    ends
  17.  
  18. SCREEN_WIDTH_IN_BYTES    equ    80
  19. DISPLAY_MEMORY_SEGMENT    equ    0a000h
  20. SC_INDEX    equ    3c4h    ;Sequence Controller Index register
  21. MAP_MASK    equ    2    ;index of Map Mask register
  22. GC_INDEX    equ    03ceh    ;Graphics Controller Index reg
  23. GRAPHICS_MODE    equ    5    ;index of Graphics Mode reg
  24. BIT_MASK    equ    8    ;index of Bit Mask reg
  25.  
  26. Data    segment    para common 'DATA'
  27. ;
  28. ; Current location of "A" as it is animated across the screen.
  29. ;
  30. CurrentX    dw    ?
  31. CurrentY    dw    ?
  32. RemainingLength    dw    ?
  33. ;
  34. ; Chunky bit-map image of a yellow "A" on a bright blue background
  35. ;
  36. AImage        label    byte
  37.         dw    13, 13        ;width, height in pixels
  38.         db    000h, 000h, 000h, 000h, 000h, 000h, 000h
  39.         db    009h, 099h, 099h, 099h, 099h, 099h, 000h
  40.         db    009h, 099h, 099h, 099h, 099h, 099h, 000h
  41.         db    009h, 099h, 099h, 0e9h, 099h, 099h, 000h
  42.         db    009h, 099h, 09eh, 0eeh, 099h, 099h, 000h
  43.         db    009h, 099h, 0eeh, 09eh, 0e9h, 099h, 000h
  44.         db    009h, 09eh, 0e9h, 099h, 0eeh, 099h, 000h
  45.         db    009h, 09eh, 0eeh, 0eeh, 0eeh, 099h, 000h
  46.         db    009h, 09eh, 0e9h, 099h, 0eeh, 099h, 000h
  47.         db    009h, 09eh, 0e9h, 099h, 0eeh, 099h, 000h
  48.         db    009h, 099h, 099h, 099h, 099h, 099h, 000h
  49.         db    009h, 099h, 099h, 099h, 099h, 099h, 000h
  50.         db    000h, 000h, 000h, 000h, 000h, 000h, 000h
  51. Data    ends
  52.  
  53. Code    segment    para public 'CODE'
  54.     assume    cs:Code, ds:Data
  55. Start    proc    near
  56.     mov    ax,Data
  57.     mov    ds,ax
  58.     mov    ax,10h
  59.     int    10h        ;select video mode 10h (640x350)
  60. ;
  61. ; Prepare for animation.
  62. ;
  63.     mov    [CurrentX],0
  64.     mov    [CurrentY],200
  65.     mov    [RemainingLength],600    ;move 600 times
  66. ;
  67. ; Animate, repeating RemainingLength times. It's unnecessary to erase
  68. ; the old image, since the one pixel of blank fringe around the image
  69. ; erases the part of the old image not overlapped by the new image.
  70. ;
  71. AnimationLoop:
  72.     mov    bx,[CurrentX]
  73.     mov    cx,[CurrentY]
  74.     mov    si,offset AImage
  75.     call    DrawFromChunkyBitmap    ;draw the "A" image
  76.     inc    [CurrentX]        ;move one pixel to the right
  77.     dec    [RemainingLength]
  78.     jnz    AnimationLoop
  79. ;
  80. ; Wait for a key before returning to text mode and ending.
  81. ;
  82.     mov    ah,01h
  83.     int    21h
  84.     mov    ax,03h
  85.     int    10h
  86.     mov    ah,4ch
  87.     int    21h
  88. Start    endp
  89. ;
  90. ; Draw an image stored in a chunky-bit map into planar VGA/EGA memory
  91. ; at the specified location.
  92. ;
  93. ; Input:
  94. ;    BX = X screen location at which to draw the upper left corner
  95. ;        of the image
  96. ;    CX = Y screen location at which to draw the upper left corner
  97. ;        of the image
  98. ;    DS:SI = pointer to chunky image to draw, as follows:
  99. ;        word at 0: width of image, in pixels
  100. ;        word at 2: height of image, in pixels
  101. ;        byte at 4: msb/lsb = first & second chunky pixels,
  102. ;            repeating for the remainder of the scan line
  103. ;            of the image, then for all scan lines. Images
  104. ;            with odd widths have an unused null nibble
  105. ;            padding each scan line out to a byte width
  106. ;
  107. ; AX, BX, CX, DX, SI, DI, ES destroyed.
  108. ;
  109. DrawFromChunkyBitmap    proc    near
  110.     cld
  111. ;
  112. ; Select write mode 2.
  113. ;
  114.     mov    dx,GC_INDEX
  115.     mov    al,GRAPHICS_MODE
  116.     out    dx,al
  117.     inc    dx
  118.     mov    al,02h
  119.     out    dx,al
  120. ;
  121. ; Enable writes to all 4 planes.
  122. ;
  123.     mov    dx,SC_INDEX
  124.     mov    al,MAP_MASK
  125.     out    dx,al
  126.     inc    dx
  127.     mov    al,0fh
  128.     out    dx,al
  129. ;
  130. ; Point ES:DI to the display memory byte in which the first pixel
  131. ; of the image goes, with AH set up as the bit mask to access that
  132. ; pixel within the addressed byte.
  133. ;
  134.     mov    ax,SCREEN_WIDTH_IN_BYTES    
  135.     mul    cx        ;offset of start of top scan line
  136.     mov    di,ax
  137.     mov    cl,bl
  138.     and    cl,111b
  139.     mov    ah,80h        ;set AH to the bit mask for the
  140.     shr    ah,cl        ; initial pixel
  141.     shr    bx,1
  142.     shr    bx,1
  143.     shr    bx,1        ;X in bytes
  144.     add    di,bx        ;offset of upper left byte of image
  145.     mov    bx,DISPLAY_MEMORY_SEGMENT
  146.     mov    es,bx        ;ES:DI points to the byte at which the
  147.                 ; upper left of the image goes
  148. ;
  149. ; Get the width and height of the image.
  150. ;
  151.     mov    cx,[si]        ;get the width
  152.     inc    si
  153.     inc    si
  154.     mov    bx,[si]        ;get the height
  155.     inc    si
  156.     inc    si
  157.     mov    dx,GC_INDEX
  158.     mov    al,BIT_MASK
  159.     out    dx,al        ;leave the GC Index register pointing
  160.     inc    dx        ; to the Bit Mask register
  161. RowLoop:
  162.  
  163.     push    ax        ;preserve the left column's bit mask
  164.     push    cx        ;preserve the width
  165.     push    di        ;preserve the destination offset
  166.  
  167. ColumnLoop:
  168.     mov    al,ah
  169.     out    dx,al        ;set the bit mask to draw this pixel
  170.     mov    al,es:[di]    ;load the latches
  171.     mov    al,[si]        ;get the next two chunky pixels
  172.     shr    al,1
  173.     shr    al,1
  174.     shr    al,1
  175.     shr    al,1        ;move the first pixel into the lsb
  176.     stosb            ;draw the first pixel
  177.     ror    ah,1        ;move mask to next pixel position
  178.     jc    CheckMorePixels    ;is next pixel in the adjacent byte?
  179.     dec    di        ;no
  180.  
  181. CheckMorePixels:
  182.     dec    cx        ;see if there are any more pixels
  183.     jz    AdvanceToNextScanLine ; across in image
  184.     mov    al,ah
  185.     out    dx,al        ;set the bit mask to draw this pixel
  186.     mov    al,es:[di]    ;load the latches
  187.     lodsb            ;get the same two chunky pixels again
  188.                 ; and advance pointer to the next
  189.                 ; two pixels
  190.     stosb            ;draw the second of the two pixels
  191.     ror    ah,1        ;move mask to next pixel position
  192.     jc    CheckMorePixels2 ;is next pixel in the adjacent byte?
  193.     dec    di        ;no
  194.  
  195. CheckMorePixels2:
  196.     loop    ColumnLoop    ;see if there are any more pixels
  197.                 ; across in the image
  198.     jmp    short CheckMoreScanLines
  199.  
  200. AdvanceToNextScanLine:
  201.     inc    si        ;advance to the start of the next
  202.                 ; scan line in the image
  203.  
  204. CheckMoreScanLines:
  205.     pop    di        ;get back the destination offset
  206.     pop    cx        ;get back the width
  207.     pop    ax        ;get back the left column's bit mask
  208.     add    di,SCREEN_WIDTH_IN_BYTES
  209.                 ;point to the start of the next scan
  210.                 ; line of the image
  211.     dec    bx        ;see if there are any more scan lines
  212.     jnz    RowLoop        ; in the image
  213.     ret
  214. DrawFromChunkyBitmap    endp
  215. Code    ends
  216.     end    Start
  217.  
  218.